#include <iostream>

using std::cout;
using std::endl;

class Data
{
public:
    Data(int data = 0)
    : _data(data)
    {
        cout << "Data(int = 0)" << endl;
    }

    int getData() const
    {
        return _data;
    }

    ~Data()
    {
        cout << "~Data()" << endl;
    }
private:
    int _data;
};

class SecondLayer
{
public:
    SecondLayer(Data *pdata)
    : _pdata(pdata)
    {
        cout << "SecondLayer(Data *)" << endl;
    }

    //重载箭头访问运算符
    Data *operator->()
    {
        return _pdata;
    }

    Data &operator*()
    {
        return *_pdata;
    }

    ~SecondLayer()
    {
        cout << "~SecondLayer()" << endl;
        if(_pdata)
        {
            delete _pdata;
            _pdata = nullptr;
        }
    }
private:
    Data *_pdata;
};

class ThirdLayer
{
public:
    ThirdLayer(SecondLayer *psl)
    : _psl(psl)
    {
        cout << "ThirdLayer(SecondLayer *)" << endl;
    }

    //重载了箭头访问运算符
    SecondLayer &operator->()
    {
        return *_psl;
    }

    ~ThirdLayer()
    {
        cout << "~ThirdLayer()" << endl;
        if(_psl)
        {
            delete _psl;
            _psl = nullptr;
        }
    }
private:
    SecondLayer *_psl;
};

void test()
{
    //sl本身只是一个栈对象，并不是一个指针，但是sl的使用与
    //普通指针没有什么区别,原因是堆SecondLayer进行了
    //箭头与解引用运算符的重载
    //sl可以利用栈对象的销毁执行自己的析构函数，然后将托管的
    //堆空间进行自动回收, 将这种指针具备智能指针的雏形
    SecondLayer sl(new Data(10)); //sl也是栈对象
    /* sl.operator->()->getData(); */ 
    cout << "sl->getData() = " << sl->getData() << endl; 
    /* sl.operator*().getData(); */
    cout << "(*sl).getData() = " << (*sl).getData() << endl; 

    /* ThirdLayer tl(new SecondLayer(new Data(200)));//tl是栈对象 */
    /* tl.operator->().operator->()->getData(); */
    /* cout << "tl->getData() = " << tl->getData() << endl; */
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

